Use case: HAL CORDIC calculate in DMA mode

Sequence diagram

CORDIC calculation in DMA mode

  @startuml

  participant "User application\n(thread mode)" as appli
  participant "<b>HAL CORDIC</b>" as cordic
  participant "<b>HAL DMA</b>" as dma
  participant "DMA IRQ handler" as dma_isr

  == Initialization / configuration ==
  appli -> cordic : HAL_CORDIC_Init(&hcordic)
  appli -> cordic : HAL_CORDIC_Configure(&hcordic, &cordic_config)
  appli -> dma : HAL_DMA_Init(hGPDMAx_CH0)\n(request: CORDIC_WRITE)
  appli -> dma : HAL_DMA_Init(hGPDMAx_CH1)\n(request: CORDIC_READ)
  appli -> cordic : __HAL_LINKDMA(hcordic, hdmaIn, hGPDMAx_CH0)\n__HAL_LINKDMA(hcordic, hdmaOut, hGPDMAx_CH1)

  == Calculation ==
  appli -> cordic : HAL_CORDIC_Calculate_DMA(&hcordic, input_data, output_data, n, CORDIC_DMA_DIR_IN_OUT)
  cordic --> appli : HAL status

  == DMA IRQ / callbacks ==
  dma_isr -> dma : DMAx_IRQHandler()\nHAL_DMA_IRQHandler(...)
  dma -> cordic : DMA callbacks
  cordic -> appli : HAL_CORDIC_CalculateCpltCallback(&hcordic)\n/ HAL_CORDIC_ErrorCallback(&hcordic)

  @enduml

Code snippet

HAL1

HAL2

 #define INPUT_BUFFER_SIZE 4U
 #define OUTPUT_BUFFER_SIZE 4U

 int32_t input_data[INPUT_BUFFER_SIZE] =  {0x80000000, 0x90000000, 0xA0000000, 0xB0000000};
 int32_t output_data[OUTPUT_BUFFER_SIZE] = {0U};









 CORDIC_HandleTypeDef hcordic;
 DMA_HandleTypeDef hGPDMA1_CH0;
 DMA_HandleTypeDef hGPDMA1_CH1;
 CORDIC_ConfigTypeDef cordic_config;

 hcordic.Instance = CORDIC;
 HAL_CORDIC_Init(&hcordic);

__HAL_RCC_CORDIC_CLK_ENABLE();

 cordic_config.Function         = CORDIC_FUNCTION_SINE;
 cordic_config.Precision        = CORDIC_PRECISION_6CYCLES;
 cordic_config.Scale            = CORDIC_SCALE_0;
 cordic_config.NbWrite          = CORDIC_NBWRITE_1;
 cordic_config.NbRead           = CORDIC_NBREAD_1;
 cordic_config.InSize           = CORDIC_INSIZE_32BITS;
 cordic_config.OutSize          = CORDIC_OUTSIZE_32BITS;

 HAL_CORDIC_Configure(&hcordic, &cordic_config)

__HAL_RCC_GPDMA1_CLK_ENABLE();

hGPDMA1_CH0.Instance = GPDMA1_Channel0;
hGPDMA1_CH0.Init.Request = GPDMA1_REQUEST_CORDIC_WRITE;
hGPDMA1_CH0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
hGPDMA1_CH0.Init.Direction = DMA_MEMORY_TO_PERIPH;
hGPDMA1_CH0.Init.SrcInc = DMA_SINC_INCREMENTED;
hGPDMA1_CH0.Init.DestInc = DMA_DINC_FIXED;
hGPDMA1_CH0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
hGPDMA1_CH0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
hGPDMA1_CH0.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
hGPDMA1_CH0.Init.SrcBurstLength = 1;
hGPDMA1_CH0.Init.DestBurstLength = 1;
hGPDMA1_CH0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
hGPDMA1_CH0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
hGPDMA1_CH0.Init.Mode = DMA_NORMAL;
HAL_DMA_Init(&hGPDMA1_CH0);

HAL_NVIC_SetPriority(GPDMA1_Channel0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel0_IRQn);

__HAL_LINKDMA(hcordic, hdmaIn, hGPDMA1_CH0);

__HAL_RCC_GPDMA1_CLK_ENABLE();

hGPDMA1_CH1.Instance = GPDMA1_Channel1;
hGPDMA1_CH1.Init.Request = GPDMA1_REQUEST_CORDIC_READ;
hGPDMA1_CH1.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
hGPDMA1_CH1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hGPDMA1_CH1.Init.SrcInc = DMA_SINC_FIXED;
hGPDMA1_CH1.Init.DestInc = DMA_DINC_INCREMENTED;
hGPDMA1_CH1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
hGPDMA1_CH1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
hGPDMA1_CH1.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
hGPDMA1_CH1.Init.SrcBurstLength = 1;
hGPDMA1_CH1.Init.DestBurstLength = 1;
hGPDMA1_CH1.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
hGPDMA1_CH1.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
hGPDMA1_CH1.Init.Mode = DMA_NORMAL;
HAL_DMA_Init(&hGPDMA1_CH1);

HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn);

__HAL_LINKDMA(hcordic, hdmaOut, hGPDMA1_CH1);

 HAL_CORDIC_Calculate_DMA(&hcordic, input_data, output_data, 4, CORDIC_DMA_DIR_IN_OUT);

 /* Wait for the callbacks:
    HAL_CORDIC_CalculateCpltCallback()

    HAL_CORDIC_ErrorCallback() */
#define INPUT_BUFFER_SIZE 4U
#define OUTPUT_BUFFER_SIZE 4U

int32_t input_data[INPUT_BUFFER_SIZE] =  {0x80000000, 0x90000000, 0xA0000000, 0xB0000000};
int32_t output_data[OUTPUT_BUFFER_SIZE] = {0U};

hal_cordic_buffer_desc_t input_buffer = {
    .p_data = input_data,
    .size_word = INPUT_BUFFER_SIZE};

hal_cordic_buffer_desc_t output_buffer = {
    .p_data = output_data,
    .size_word = OUTPUT_BUFFER_SIZE};

hal_cordic_handle_t hcordic;
hal_dma_handle_t hLPDMA1_CH0;
hal_dma_handle_t hLPDMA1_CH1;
hal_cordic_config_t cordic_config;


HAL_CORDIC_Init(&hcordic, HAL_CORDIC);

HAL_RCC_CORDIC_EnableClock();

cordic_config.function   = HAL_CORDIC_FUNCTION_SINE;
cordic_config.precision  = HAL_CORDIC_PRECISION_6_CYCLE;
cordic_config.scaling_factor  = HAL_CORDIC_SCALING_FACTOR_0;
cordic_config.nb_args    = HAL_CORDIC_NB_ARG_1;
cordic_config.nb_results = HAL_CORDIC_NB_RESULT_1;
cordic_config.in_width    = HAL_CORDIC_IN_WIDTH_32_BIT;
cordic_config.out_width   = HAL_CORDIC_OUT_WIDTH_32_BIT;

HAL_CORDIC_SetConfig(&hcordic,&cordic_config);

HAL_RCC_LPDMA1_EnableClock();

HAL_DMA_Init(&hLPDMA1_CH0, HAL_LPDMA1_CH0);




hal_dma_direct_xfer_config_t xfer_cfg_cordic_wr_dma;
xfer_cfg_cordic_wr_dma.request         = HAL_LPDMA1_REQUEST_CORDIC_WR;
xfer_cfg_cordic_wr_dma.direction       = HAL_DMA_DIRECTION_MEMORY_TO_PERIPH;
xfer_cfg_cordic_wr_dma.src_inc         = HAL_DMA_SRC_ADDR_INCREMENTED;
xfer_cfg_cordic_wr_dma.dest_inc        = HAL_DMA_DEST_ADDR_FIXED;
xfer_cfg_cordic_wr_dma.src_data_width  = HAL_DMA_SRC_DATA_WIDTH_WORD;
xfer_cfg_cordic_wr_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_WORD;
xfer_cfg_cordic_wr_dma.priority        = HAL_DMA_PRIORITY_LOW_WEIGHT_LOW;

HAL_DMA_SetConfigPeriphDirectXfer(&hLPDMA1_CH0, &xfer_cfg_cordic_wr_dma);

HAL_CORTEX_NVIC_SetPriority(LPDMA1_CH0_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
HAL_CORTEX_NVIC_EnableIRQ(LPDMA1_CH0_IRQn);

HAL_CORDIC_SetWriteDMA(&hCORDIC, &hLPDMA1_CH0);

HAL_RCC_LPDMA1_EnableClock();

HAL_DMA_Init(&hLPDMA1_CH1, HAL_LPDMA1_CH1);




hal_dma_direct_xfer_config_t xfer_cfg_cordic_rd_dma;
xfer_cfg_cordic_rd_dma.request         = HAL_LPDMA1_REQUEST_CORDIC_RD;
xfer_cfg_cordic_rd_dma.direction       = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
xfer_cfg_cordic_rd_dma.src_inc         = HAL_DMA_SRC_ADDR_FIXED;
xfer_cfg_cordic_rd_dma.dest_inc        = HAL_DMA_DEST_ADDR_INCREMENTED;
xfer_cfg_cordic_rd_dma.src_data_width  = HAL_DMA_SRC_DATA_WIDTH_WORD;
xfer_cfg_cordic_rd_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_WORD;
xfer_cfg_cordic_rd_dma.priority        = HAL_DMA_PRIORITY_LOW_WEIGHT_LOW;

HAL_DMA_SetConfigPeriphDirectXfer(&hLPDMA1_CH1, &xfer_cfg_cordic_rd_dma);

HAL_CORTEX_NVIC_SetPriority(LPDMA1_CH1_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
HAL_CORTEX_NVIC_EnableIRQ(LPDMA1_CH1_IRQn);

HAL_CORDIC_SetReadDMA(&hCORDIC, &hLPDMA1_CH1);

HAL_CORDIC_Calculate_DMA(&hcordic, &input_buffer, &output_buffer);

/* Wait for the callbacks:
   HAL_CORDIC_CalculateCpltCallback()
   HAL_CORDIC_WriteCpltCallback()
   HAL_CORDIC_ErrorCallback() */

Key changes

  1. HAL2 configures CORDIC DMA channels explicitly using HAL_CORDIC_SetWriteDMA() and HAL_CORDIC_SetReadDMA().

  2. HAL2 uses hal_dma_direct_xfer_config_t and HAL_DMA_SetConfigPeriphDirectXfer() to configure DMA transfers.

  3. HAL2 introduces additional callbacks for split DMA streams (for example, HAL_CORDIC_WriteCpltCallback()).